package com.thinkgem.jeesite.common.log;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.log4j.LogManager;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.thinkgem.jeesite.common.utils.IdGen;
// import com.elangzhi.common.utils.UUIDFactory;
import com.thinkgem.jeesite.common.utils.StringUtils;
import com.thinkgem.jeesite.modules.sys.entity.Log;
import com.thinkgem.jeesite.modules.sys.service.LogService;

/**
 * 切点类
 * @author GaoXiang
 * @since 2016/10/26
 * @version 1.0
 */
@Aspect
@Component
public  class AdminLogAspect {

    //注入Service用于把日志保存数据库
    @Resource
    // private LogService logService;
    private LogService logService;

    //Controller层切点
    @Pointcut("@annotation(com.elangzhi.common.log.AdminControllerLog)")
    public  void controllerAspect() { }
    private static org.apache.log4j.Logger logger = LogManager.getLogger("controllerAspect");
    /**
     * 前置通知 用于拦截Controller层记录用户的操作
     *
     * @param joinPoint 切点
     */
    @Before("controllerAspect()")
    public  void doBefore(JoinPoint joinPoint) {
    	
        HttpServletRequest request = getRequest();
        HttpSession session = request.getSession();
        //请求的IP
        String ip = request.getRemoteAddr();
        try {
            //*========控制台输出=========*//
        	logger.info("===============================请求日志【开始】===================================");
        	logger.info("请求方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));
        	logger.info("方法描述:" + getControllerMethodDescription(joinPoint));
        	logger.info("来源地址:" + ip);
            //*========数据库日志=========*//
            Log log = new Log();
            log.setId(IdGen.getStringId());
            
            // 获取日志类型 zhangad 2017-03-20
            String type = getControllerMethodType(joinPoint);
            if(StringUtils.isEmpty(type))
            {
            	type = "1";
            }
            
            // log.setType(1);
            log.setType(type);
            log.setCreateDate(new Date());
            log.setTitle(getControllerMethodDescription(joinPoint) );
            log.setMethod((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));
            log.setRemoteAddr(ip);
            log.setParams(Arrays.toString(joinPoint.getArgs()));
            log.getCreateBy().setId("1");
            logService.save(log);
            logger.info("===============================请求日志【结束】===================================");
        }  catch (Exception e) {
        	logger.info("=============================== 日志记录失败【异常】 ===================================");
        }
    }


    /**
     * 获取注解中对方法的描述信息 用于Controller层注解
     *
     * @param joinPoint 切点
     * @return 方法描述
     * @throws Exception 获取注解失败
     */
    private  static String getControllerMethodDescription(JoinPoint joinPoint)  throws Exception {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method m = signature.getMethod();
        return m.getAnnotation(AdminControllerLog. class).description();
    }
    
    /**
     * 获取注解中对方法的日志类型 用于Controller层注解
     *
     * @param joinPoint 切点
     * @return 方法描述
     * @throws Exception 获取注解失败
     * @author zhangad 2017-03-20
     */
    private  static String getControllerMethodType(JoinPoint joinPoint)  throws Exception {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method m = signature.getMethod();
        return m.getAnnotation(AdminControllerLog. class).type();
    }

    private static HttpServletRequest  getRequest(){
       return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }
}